#include "Cats/CatStates/CatState.h"
#include "Cats/CatStates/CatState_Witch_Attack.h"
#include "Cats/BaseCat.h"
#include "Cats/CatSpriteLoader.h"
#include "Character/Character.h"

#include "Supporting/SoundLoader.h"
#include "Supporting/Enums/EnumSoundType.h"

CatState_Witch_Attack::CatState_Witch_Attack(BaseCat* pCatRef):CatState(pCatRef)
{
	_projectileLayer = 0;
	_projDeathDuration = 0;

}

CatState_Witch_Attack::~CatState_Witch_Attack()
{
	if (_projectileLayer == 0)
		return;

	_projectileLayer->removeFromParent();
	_projectileLayer = 0;
}

void CatState_Witch_Attack::runOnEnter()
{
	// Sound
	SoundLoader::playSound(WITCH_SHOOT_SOUND);

	//play attack animation
	_pCatRef->stopActionByTag(CatSpriteLoader::SPRITE_CAT_TAG);
	_pCatRef->runAction(CatSpriteLoader::getCatAnimation(_pCatRef->getCatType(), CAT_ANIM_ATTACK));
	_attackAnimDuration = CatSpriteLoader::getAnimationDuration(_pCatRef->getCatType(), CAT_ANIM_ATTACK);

	//create and launch projectile
	if (_projectileLayer == 0)
	{
		_projectileLayer = CCSprite::create();
		_projectileLayer->setScale(_pCatRef->getScale());
		//use global coordinates for the projectile
		_pCatRef->getParent()->addChild(_projectileLayer);

	}
	_projectileLayer->stopAllActions();
	_projectileLayer->setPosition(_pCatRef->getPosition());
	_projectileLayer->runAction(CatSpriteLoader::getCatProjectileAnimation(_pCatRef->getCatType(), CAT_ANIM_PROJ_LAUNCH));
	_projLaunchDuration = CatSpriteLoader::getAnimationDuration(_pCatRef->getCatType(), CAT_ANIM_PROJ_LAUNCH);

	//reset variables for destroying projectile
	_hasHit = false;
	_projDeathDuration = 0;
}

void CatState_Witch_Attack::update(float timeDiff)
{
	//if projectile has hit the character
	if (_hasHit)
	{
		if (_projDeathDuration == 0) //play exploding animation
		{
			_projectileLayer->stopAllActions();
			_projectileLayer->runAction(CatSpriteLoader::getCatProjectileAnimation(_pCatRef->getCatType(), CAT_ANIM_PROJ_DEATH));
			_projDeathDuration = CatSpriteLoader::getAnimationDuration(_pCatRef->getCatType(), CAT_ANIM_PROJ_DEATH);
		}
		else
		{
			_projDeathDuration -= timeDiff;
			if (_projDeathDuration <= 0)
				_pCatRef->setNextCatState(CAT_CHASE); //attempt to move closer.
		}
	}
	else
	{
		//check for attack animaton change
		if (_attackAnimDuration > 0)
		{
			_attackAnimDuration -= timeDiff;
			//change animation to walk animation
			if (_attackAnimDuration <= 0)
			{
				_pCatRef->stopAllActions();
				_pCatRef->runAction(CatSpriteLoader::getCatAnimation(_pCatRef->getCatType(), CAT_ANIM_WALK));
			}
		}

		//check for animation change for projectile
		if (_projLaunchDuration > 0)
		{
			_projLaunchDuration -= timeDiff;
			//change animation to fly
			if (_projLaunchDuration <= 0)
			{
				_projectileLayer->stopAllActions();
				_projectileLayer->runAction(CatSpriteLoader::getCatProjectileAnimation(_pCatRef->getCatType(), CAT_ANIM_PROJ_FLY));
			}
		}

		//calculate the speed and direction of projectile (homing)
		float speed = (_pCatRef->getAttackSpeedX()/2 * timeDiff) * _pCatRef->getSpeedMultiplier();

		//homing direction
		float targetX = _pCharRef->getPositionX() - _projectileLayer->getPositionX();
		float targetY = _pCharRef->getPositionY() - _projectileLayer->getPositionY();
		float rotation = atan2(targetY, targetX) * 180 / 3.14159;

		//MATH for proportionately correct X, Y speed
		float speedX = speed * (90 - abs(rotation)) / 90;
		float speedY;
		if(rotation < 0)
			speedY = -speed + abs(speedX);
		else
			speedY = speed - abs(speedX);

		//move the projectile using the newly calculated speed
		_projectileLayer->setPositionX(_projectileLayer->getPositionX() + speedX);
		_projectileLayer->setPositionY(_projectileLayer->getPositionY() + speedY);

		//check collision with character
		if ( _projectileLayer->boundingBox().intersectsRect(_pCharRef->getRect()))
		{
			//reduce character health
			_pCharRef->reduceHealth(_pCatRef->getBaseAttackDamage());

			//wait for exploding animation to finish
			_hasHit = true;
		}
	}
}

void CatState_Witch_Attack::onExit()
{
	CatState::onExit();
	if (_projectileLayer == 0)
		return;

	if (!_hasHit)
	{
		_projectileLayer->stopAllActions();
		_projectileLayer->runAction(CatSpriteLoader::getCatProjectileAnimation(_pCatRef->getCatType(), CAT_ANIM_PROJ_DEATH));

	}
}

void CatState_Witch_Attack::onPause()
{
	CatState::onPause();

	onExit();
}
